package com.imooc.springcloud.biz;

import com.imooc.springcloud.topic.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @date 2021-04-02
 * @author zkw
 */
@RestController
@Slf4j
public class Controller {

    @Autowired
    private MyTopic myTopic;

    @Autowired
    private GroupTopic groupTopic;

    @Autowired
    private DelayedTopic delayedTopic;

    @Autowired
    private ErrorTopic errorTopic;

    @Autowired
    private RequeueTopic requeueTopic;

    @Autowired
    private DlqTopic dlqTopic;

    @Autowired
    private FallbackTopic fallbackTopic;

    @PostMapping("send")
    public void sendMessage(@RequestParam("body") String body) {
        myTopic.output().send(MessageBuilder.withPayload(body).build());
    }

    @PostMapping("sendToGroup")
    public void sendMessageToGroup(@RequestParam("body") String body) {
        groupTopic.output().send(MessageBuilder.withPayload(body).build());
    }

    @PostMapping("sendDM")
    public void sendDelayedMessage(@RequestParam("body") String body,
                                   @RequestParam("seconds") Integer seconds) {
        MessageBean msg = new MessageBean();
        msg.setPayload(body);
        log.info("read to send delayed message");
        delayedTopic.output().send(
                MessageBuilder.withPayload(msg)
                        .setHeader("x-delay", 1000 * seconds)
                        .build());
    }

    /**
     * 异常重试（单机版）
     * @param body
     */
    @PostMapping("sendError")
    public void sendErrorMessage(@RequestParam("body") String body) {
        MessageBean msg = new MessageBean();
        msg.setPayload(body);
        errorTopic.output().send(MessageBuilder.withPayload(msg).build());
    }

    /**
     * 异常重试（联机版-重新入列）
     * @param body
     */
    @PostMapping("requeue")
    public void sendErrorMessageToMQ(@RequestParam("body") String body) {
        MessageBean msg = new MessageBean();
        msg.setPayload(body);
        requeueTopic.output().send(MessageBuilder.withPayload(msg).build());
    }

    @PostMapping("dlq")
    public void sendMessageToDlq(@RequestParam("body") String body) {
        MessageBean msg = new MessageBean();
        msg.setPayload(body);
        dlqTopic.output().send(MessageBuilder.withPayload(msg).build());
    }

    /**
     * fallback + 版本升级
     * @param body
     * @param version
     */
    @PostMapping("fallback")
    public void sendMessageToFallback(@RequestParam("body") String body,
                                      @RequestParam("version") String version) {
        MessageBean msg = new MessageBean();
        msg.setPayload(body);

        /**
         * 下单场景：不同的手机APP调用的接口版本不一样
         * 老版本：placeOrderV1
         * 升级后的app调用的版本：placeOrderV2
         * 调用的时候决定走哪个调用逻辑
         * 这种接口调用方案类比到消息驱动场景：
         * 在调用下游方法，或者说在生成message的时候，指定版本
         * 1.message发送到不同的队列 queue1、queue2
         * 2.传递一个信息到下游（对代码的改动越小越好）
         */

        fallbackTopic.output().send(
                MessageBuilder.withPayload(msg)
                        .setHeader("version", version)
                        .build());
    }

}
